package me.ingxin.android.badge

import android.view.View
import android.view.ViewGroup
import kotlin.math.roundToInt

/**
 * Created by ingxin on 2022/12/16
 * 兄弟view的elevation属性可能会造成遮挡
 */
abstract class Badge(
    private val badgeDrawable: BadgeDrawable,
    private val anchor: View,
    private val gravity: Gravity
) {

    private var vOffset = 0
    private var hOffset = 0

    init {
        bindAnchor()
        update()
    }

    /**
     * 隐藏或显示角标
     * @param show true显示，false隐藏
     */
    fun setVisibility(show: Boolean) {
        if (show) {
            bindAnchor()
            update()
        } else {
            anchor.overlay.remove(badgeDrawable)
        }
    }

    /**
     * 设置角标在垂直方向的偏移量,默认情况badge中心点和[Badge.anchor]4个顶点中的一个重合
     * @param verticalPx 水平方向偏移像素值
     * @param horizontalPx 竖直方向偏移像素值
     */
    fun setOffset(horizontalPx: Int,verticalPx: Int) {
        vOffset = verticalPx
        hOffset = horizontalPx
        update()
    }


    fun getWidth(): Int {
        return badgeDrawable.intrinsicWidth
    }

    fun getHeight(): Int {
        return badgeDrawable.intrinsicHeight
    }

    protected fun update() {
        val anchorWidth = anchor.width
        val anchorHeight = anchor.height
        if (anchorWidth != 0 && anchorHeight != 0 || gravity == Gravity.TopStart) {
            update(anchorWidth, anchorHeight)
        } else {
            anchor.post { update(anchor.width, anchor.height) }
        }
    }

    private fun update(anchorWidth: Int, anchorHeight: Int) {
        val w = badgeDrawable.intrinsicWidth
        val h = badgeDrawable.intrinsicHeight

        var top = 0
        var left = 0
        when (gravity) {
            Gravity.TopEnd -> {
                top = -(h / 2f).roundToInt()
                left = (anchorWidth - w + w / 2f).roundToInt()
            }

            Gravity.TopStart -> {
                top = -(h / 2f).roundToInt()
                left = -(w / 2f).roundToInt()
            }

            Gravity.BottomEnd -> {
                top = (anchorHeight - h + h / 2f).roundToInt()
                left = (anchorWidth - w + w / 2f).roundToInt()
            }

            Gravity.BottomStart -> {
                top = (anchorHeight - h + h / 2f).roundToInt()
                left = -(w / 2f).roundToInt()
            }

        }
        top += vOffset
        left += hOffset

        badgeDrawable.setBounds(left, top, left + w, top + h)
        badgeDrawable.invalidateSelf()
    }

    private fun bindAnchor() {
        val anchorViewParent = anchor.parent as ViewGroup
        anchorViewParent.clipChildren = false
        anchorViewParent.clipToPadding = false
        anchor.overlay.add(badgeDrawable)
    }

    /**
     * 角标位置
     */
    enum class Gravity {
        /**badge中心点在view右上角顶点*/
        TopEnd,

        /**badge中心点在view左上角顶点*/
        TopStart,

        /**badge中心点在view右下角顶点*/
        BottomEnd,

        /**badge中心点在view左下角顶点*/
        BottomStart
    }

}